package edu.pku.sei.transformation.editor.controller.editparts.node;

import java.beans.PropertyChangeEvent;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseMotionListener;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.DirectEditPolicy;
import org.eclipse.gef.requests.DirectEditRequest;

import edu.pku.sei.modeler.edit.parts.AbstractNodeEditPart;
import edu.pku.sei.modeler.model.structure.MetaShapeElement;
import edu.pku.sei.transformation.editor.controller.commands.ChangeNameCommand;
import edu.pku.sei.transformation.editor.controller.policies.NodeComponentEditPolicy;
import edu.pku.sei.transformation.editor.model.Expression;
import edu.pku.sei.transformation.editor.model.ModelPackage;
import edu.pku.sei.transformation.editor.views.figures.ExpressionFigure;

public class ExpressionEditpart extends AbstractNodeEditPart {
	boolean hightLightVariable = false;

	public ExpressionEditpart(MetaShapeElement model) {
		super(model);
	}

	@Override
	protected DirectEditPolicy createDirectEditPolicy() {
		return new DirectEditPolicy() {
			protected Command getDirectEditCommand(DirectEditRequest request) {
				return new ChangeNameCommand((String) request.getCellEditor()
						.getValue(), getExpression());
			}

			protected void showCurrentEditValue(DirectEditRequest request) {
				ExpressionFigure figure = (ExpressionFigure) getFigure();
				figure.setText(getExpression().getExp());
				figure.getUpdateManager().performUpdate();
			}
		};
	}

	@Override
	protected IFigure createFigure() {
		ExpressionFigure figure = new ExpressionFigure();
		figure.addMouseMotionListener(new MouseMotionListener() {

			@Override
			public void mouseDragged(MouseEvent me) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseEntered(MouseEvent me) {

			}

			@Override
			public void mouseExited(MouseEvent me) {
				if (hightLightVariable
						&& getExpression().getSyntaxTree() != null) {
					getExpression().getSyntaxTree().cancelHighLightNotify();
					hightLightVariable = false;
				}

			}

			@Override
			public void mouseHover(MouseEvent me) {
				if (getExpression().getSyntaxTree() != null) {
					getExpression().bind();
					getExpression().getSyntaxTree().sendHighLightNotify();
					hightLightVariable = true;
				}
			}

			@Override
			public void mouseMoved(MouseEvent me) {
				// TODO Auto-generated method stub

			}

		});
		return figure;
	}

	@Override
	protected void handlePropertyChanged(PropertyChangeEvent event) {
		String propertyName = event.getPropertyName();
		if (ModelPackage.EXPRESSION_EXP.equals(propertyName)) {
			refreshVisuals();
		} else {
			super.handlePropertyChanged(event);
		}
	}

	@Override
	protected void refreshVisuals() {
		Expression exp = getExpression();
		ExpressionFigure figure = (ExpressionFigure) getFigure();
		((ExpressionFigure) getFigure()).setText(exp.getExp());
		if (exp.getSyntaxTree() == null) {
			figure.setHighLight(true);
		} else {
			figure.setHighLight(false);
		}
		super.refreshVisuals();
	}

	private Expression getExpression() {
		return (Expression) getNode().getModelElement();
	}

	@Override
	protected void createEditPolicies() {
		super.createEditPolicies();
		installEditPolicy(EditPolicy.COMPONENT_ROLE,
				new NodeComponentEditPolicy());
	}
}
